using System;
using System.Collections.Generic;
using System.Text;
using WindowsLive.Writer.Api;
using System.IO;
using System.Web.UI;
using System.Windows.Forms;
using Wilco.SyntaxHighlighting;
using System.Web.UI.HtmlControls;

namespace CodeSyntaxHighLighter
{
	[WriterPluginAttribute
   ("C411E4BC-FA5A-4068-9F25-1AA2B5A98D76",
	"Code Syntax Highlighter",
	ImagePath = "Images.Code.bmp",
	PublisherUrl = "http://alexey.raga.name",
	HasEditableOptions = true,
	Description = "Highlights the code in your post")]

	[InsertableContentSourceAttribute("Code")]
	public class AdvancedPlugin : WindowsLive.Writer.Api.SmartContentSource
	{
		internal const int DefaultWidth = 600;
		internal const int DefaultHeight = 200;

		private IParser _parser = new HtmlParser();

		private ContentEditor _editor;
		public override WindowsLive.Writer.Api.SmartContentEditor CreateEditor(WindowsLive.Writer.Api.ISmartContentEditorSite editorSite)
		{
			_editor = new ContentEditor(editorSite);
			return _editor;
		}

		public override void EditOptions(IWin32Window dialogOwner)
		{
			base.EditOptions(dialogOwner);
		}

		public override void Initialize(IProperties pluginOptions)
		{
			base.Initialize(pluginOptions);
		}

		public override System.Windows.Forms.DialogResult CreateContent(System.Windows.Forms.IWin32Window dialogOwner, ISmartContent newContent)
		{
			using (OptionsForm form = new OptionsForm())
			{
				DialogResult res = form.ShowDialog();
				if (res == DialogResult.OK)
				{
					newContent.Properties.SetString("Code", form.CodeText);
					newContent.Properties.SetString("Language", form.Language);
				}

				return res;
			}
		}

		public override string GeneratePublishHtml(WindowsLive.Writer.Api.ISmartContent content, WindowsLive.Writer.Api.IPublishingContext publishingContext)
		{
			HtmlGenericControl div = new HtmlGenericControl("div");
			div.Style.Add("display", "block");
			div.Style.Add("margin", "2px");
			div.Style.Add("background-color", content.Properties.GetString("BackgroundColor", "#F7F7FF"));
			if (content.Properties.GetBoolean("ShowBorder", false))
			{
				div.Style.Add("border", "solid 1px gray");
			}
			else
			{
				div.Style.Add("border", "solid 0px gray");
			}
			if (content.Properties.GetBoolean("FixedSize", false))
			{
				if (content.Properties.GetBoolean("FixedWidth", false))
				{
					div.Style.Add("overflow-x", "scroll");
					div.Style.Add("width", content.Properties.GetString("Width", DefaultWidth.ToString())+"px");
				}

				if (content.Properties.GetBoolean("FixedHeight", false))
				{
					div.Style.Add("overflow-y", "scroll");
					div.Style.Add("height", content.Properties.GetString("Height", DefaultHeight.ToString())+"px");
				}
			}
			foreach (HtmlControl ctrl in GetColorizedText(content))
			{
				div.Controls.Add(ctrl);
			}

			StringBuilder sb = new StringBuilder();
			using (HtmlTextWriter writer = new HtmlTextWriter(new StringWriter(sb)))
			{
				div.RenderControl(writer);
			}

			return sb.ToString();
		}

		private IEnumerable<HtmlControl> GetColorizedText(WindowsLive.Writer.Api.ISmartContent content)
		{
			string lngKey = content.Properties.GetString("Language", "C#");
			string code = content.Properties.GetString("Code", String.Empty);
			string parsedCode = String.Empty;
			if (String.IsNullOrEmpty(code))
			{
				yield break;
			}
				
			HighlighterBase colorizer = Register.Instance.Highlighters[lngKey];
			colorizer.Parser = _parser;
			colorizer.ForceReset();
			parsedCode = colorizer.Parse(code);

			string[] lines = parsedCode.Replace("\r", String.Empty).Split('\n');

			bool displayLineNumbers = content.Properties.GetBoolean("ShowLineNumbers", false);

			//HtmlGenericControl pre = new HtmlGenericControl("pre");
			HtmlTable table = new HtmlTable();
			HtmlTableRow row;
			HtmlTableCell cell;

			for (int i = 0; i < lines.Length; i++)
			{
				row = new HtmlTableRow();
				if (displayLineNumbers)
				{
					cell = new HtmlTableCell();
					cell.InnerText = (i + 1).ToString()+".";
					row.Cells.Add(cell);
				}
				cell = new HtmlTableCell();
				cell.InnerHtml = lines[i].Replace("    ", "\t").Replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
				row.Cells.Add(cell);
				table.Rows.Add(row);
			}

			yield return table;
		}

		public override ResizeCapabilities ResizeCapabilities
		{
			get
			{
				return ResizeCapabilities.Resizable;
			}
		}

		public override void OnResizeComplete(ISmartContent content, System.Drawing.Size newSize)
		{
			content.Properties.SetString("Height", newSize.Height.ToString());
			content.Properties.SetString("Width", newSize.Width.ToString());
			base.OnResizeComplete(content, newSize);
		}
	}
}
